package org.dromara.common.encrypt.utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AESUtil {
    private static final String ALGORITHM = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";

    /**
     * AES-256-CBC加密函数
     * @param message 待加密的明文
     * @param secretKey 加密密钥，必须为32字节长度字符串
     * @return 加密后的Base64字符串，包含IV和密文
     */
    public static String encrypt(String message, String secretKey) throws Exception {
        // 生成随机IV
        byte[] ivBytes = new byte[16];
        java.security.SecureRandom secureRandom = new java.security.SecureRandom();
        secureRandom.nextBytes(ivBytes);
        IvParameterSpec iv = new IvParameterSpec(ivBytes);

        // 转换密钥
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM);

        // 加密
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        byte[] encryptedBytes = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));

        // 拼接IV和密文并转换为Base64
        byte[] combined = new byte[ivBytes.length + encryptedBytes.length];
        System.arraycopy(ivBytes, 0, combined, 0, ivBytes.length);
        System.arraycopy(encryptedBytes, 0, combined, ivBytes.length, encryptedBytes.length);

        return Base64.getEncoder().encodeToString(combined);
    }

    /**
     * AES-256-CBC解密函数
     * @param encryptedMessage 待解密的Base64字符串
     * @param secretKey 解密密钥，必须与加密密钥相同
     * @return 解密后的明文
     */
    public static String decrypt(String encryptedMessage, String secretKey) throws Exception {
        // 解码Base64
        byte[] combined = Base64.getDecoder().decode(encryptedMessage);

        // 提取IV和密文
        byte[] ivBytes = new byte[16];
        byte[] ciphertextBytes = new byte[combined.length - 16];

        System.arraycopy(combined, 0, ivBytes, 0, 16);
        System.arraycopy(combined, 16, ciphertextBytes, 0, combined.length - 16);

        IvParameterSpec iv = new IvParameterSpec(ivBytes);

        // 转换密钥
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), ALGORITHM);

        // 解密
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
        byte[] decryptedBytes = cipher.doFinal(ciphertextBytes);

        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 生成随机IV字符串（用于测试）
     */
    public static String generateRandomIV() {
        byte[] ivBytes = new byte[16];
        java.security.SecureRandom secureRandom = new java.security.SecureRandom();
        secureRandom.nextBytes(ivBytes);
        return bytesToHex(ivBytes);
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte b : bytes) {
            result.append(String.format("%02x", b));
        }
        return result.toString();
    }

    public static void main(String[] args) {
        try {
            String secretKey = "your-32-byte-secret-key-hereades"; // 必须是32字节
            String message = "需要加密的消息内容";

            // 加密
            String encrypted = encrypt(message, secretKey);
            System.out.println("加密后: " + encrypted);

            // 解密
            String decrypted = decrypt("RmoKrrKi6kfwtumrl/jEFGVnN/bcledolaOo9FbR7vxoWn1LlqcdXRWegmpsPsRg", secretKey);
            System.out.println("解密后: " + decrypted);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
